﻿using Twitterizer.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Twillo.Core.Settings;
using Twitterizer;
using System.Diagnostics;
using System.Text.RegularExpressions;

namespace Twillo.Core
{
    public static class Twitter
    {
        public static Twitterizer.OAuthTokens OAuthTokens
        {
            get
            {
                return new Twitterizer.OAuthTokens() { ConsumerKey = Twillo.Core.Settings.SettingsManager.ConsumerKey, ConsumerSecret = Twillo.Core.Settings.SettingsManager.ConsumerSecret, AccessToken = SettingsManager.AccessToken, AccessTokenSecret = SettingsManager.AccessTokenSecret };
            }
        }


        public static string Format(string status)
        {
            string value = status;
            value = Regex.Replace(value, "(^|[\n ])([\\w]+?://[\\w]+[^ \"\n\r\t< ]*)", "$1<a href=\"$2\" target=\"_blank\">$2</a>");
            value = Regex.Replace(value, "(^|[\n ])((www|ftp)\\.[^ \"\t\n\r< ]*)", "$1<a href=\"http://$2\" target=\"_blank\">$2</a>");
            value = Regex.Replace(value, "\\@(\\w+)", "<a href=\"http://www.twitter.com/$1\" target=\"_blank\">@$1</a>");
            value = Regex.Replace(value, "\\#(\\w+)", "<a href=\"http://search.twitter.com/search?q=$1\" target=\"_blank\">#$1</a>");
            return value;
        }


        public static Twitterizer.OptionalProperties OptionalProperties
        {
            get
            {
                Twitterizer.OptionalProperties prop = new Twitterizer.OptionalProperties();
                prop.UseSSL = SettingsManager.UseSSL;
                prop.Proxy = Twillo.Core.Web.Proxy.WebProxy;
                return prop;
            }
        }

        public static TwitterUser GetUser(string username)
        {
            TwitterResponse<TwitterUser> response = TwitterUser.Show(OAuthTokens, username, OptionalProperties);
            return response.ResponseObject;
        }

        public static TwitterUser Self()
        {

            return GetUser(SettingsManager.Username);
        }

        public static TwitterUserCollection SearchUsers(string query)
        {
            TwitterResponse<TwitterUserCollection> response = TwitterUser.Search(OAuthTokens, query, new UserSearchOptions() { Proxy = OptionalProperties.Proxy, UseSSL = OptionalProperties.UseSSL });
            return response.ResponseObject;
        }

        public static TwitterStatusCollection GetConversation(TwitterStatus status)
        {
            TwitterStatusCollection items = new TwitterStatusCollection();

            var statusResponse = TwitterStatus.Show(OAuthTokens, status.Id, OptionalProperties);

            if (statusResponse.Result != RequestResult.Success)
            {
                return items;
            }

            while (statusResponse != null && statusResponse.Result == RequestResult.Success && statusResponse.ResponseObject.InReplyToStatusId.HasValue)
            {
                items.Insert(0, statusResponse.ResponseObject);
                statusResponse = TwitterStatus.Show(statusResponse.ResponseObject.InReplyToStatusId.Value);
            }

            return items;
        }

        public static TwitterStatusCollection GetTimeLine(bool IncludeReTweets, int count)
        {
            TwitterResponse<TwitterStatusCollection> response = TwitterTimeline.UserTimeline(OAuthTokens, new UserTimelineOptions() { Proxy = OptionalProperties.Proxy, UseSSL = OptionalProperties.UseSSL, IncludeRetweets = IncludeReTweets, Count = count });
            return response.ResponseObject;
        }

        public static TwitterStatusCollection GetFriendTimeLine(bool IncludeReTweets, int count)
        {
            TwitterResponse<TwitterStatusCollection> response = TwitterTimeline.FriendTimeline(OAuthTokens, new TimelineOptions() { Proxy = OptionalProperties.Proxy, UseSSL = OptionalProperties.UseSSL, IncludeRetweets = IncludeReTweets, Count=count});

            return response.ResponseObject;
        }

        public static TwitterStatusCollection GetCombinedTimeLine(bool IncludeReTweets)
        {
            TwitterStatusCollection items = GetTimeLine(IncludeReTweets, SettingsManager.TimeLineCount);
            TwitterStatusCollection friendTimeline = GetFriendTimeLine(IncludeReTweets, SettingsManager.TimeLineCount);            

            foreach (TwitterStatus status in friendTimeline)
            {
                items.Add(status);
            }

            TwitterStatusCollection result = new TwitterStatusCollection();
            using (IEnumerator<TwitterStatus> sort = items.OrderByDescending(item => item.CreatedDate).ToList<TwitterStatus>().GetEnumerator())
            {
                sort.Reset();
                while (sort.MoveNext())
                {
                    result.Add(sort.Current);
                }
            }
            return result;
        }

        public static TwitterStatusCollection GetTimeLine(bool IncludeReTweets, string screenname, int count)
        {
            TwitterResponse<TwitterStatusCollection> response = TwitterTimeline.UserTimeline(OAuthTokens, new UserTimelineOptions() { Proxy = OptionalProperties.Proxy, UseSSL = OptionalProperties.UseSSL, IncludeRetweets = IncludeReTweets, ScreenName = screenname, Count = count });
            return response.ResponseObject;
        }


        public static TwitterStatusCollection GetMentions(bool IncludeReTweets, int count)
        {
            TwitterResponse<TwitterStatusCollection> response = TwitterTimeline.Mentions(OAuthTokens, new UserTimelineOptions() { Proxy = OptionalProperties.Proxy, UseSSL = OptionalProperties.UseSSL, IncludeRetweets = IncludeReTweets, Count = count });
            return response.ResponseObject;
        }

        public static TwitterStatusCollection GetPublicTimeLine(bool IncludeReTweets, int count)
        {
            TwitterResponse<TwitterStatusCollection> response = TwitterTimeline.PublicTimeline(OAuthTokens, new UserTimelineOptions() { Proxy = OptionalProperties.Proxy, UseSSL = OptionalProperties.UseSSL, IncludeRetweets = IncludeReTweets, Count = count });
            return response.ResponseObject;
        }

        public static TwitterStatusCollection GetRetweetsOfMe()
        {
            TwitterResponse<TwitterStatusCollection> response = TwitterTimeline.RetweetsOfMe(OAuthTokens, new RetweetsOfMeOptions() { Proxy = OptionalProperties.Proxy, UseSSL = OptionalProperties.UseSSL });
            return response.ResponseObject;
        }

        public static TwitterStatusCollection GetRetweetsByMe(bool IncludeReTweets)
        {
            TwitterResponse<TwitterStatusCollection> response = TwitterTimeline.RetweetedByMe(OAuthTokens, new TimelineOptions() { Proxy = OptionalProperties.Proxy, UseSSL = OptionalProperties.UseSSL, IncludeRetweets = IncludeReTweets });
            return response.ResponseObject;
        }

        public static TwitterStatusCollection GetRetweetsToMe(bool IncludeReTweets)
        {
            TwitterResponse<TwitterStatusCollection> response = TwitterTimeline.RetweetedToMe(OAuthTokens, new TimelineOptions() { Proxy = OptionalProperties.Proxy, UseSSL = OptionalProperties.UseSSL, IncludeRetweets = IncludeReTweets });
            return response.ResponseObject;
        }

        public static TwitterTrendCollection GetCurrentTrends()
        {
            TwitterResponse<TwitterTrendCollection> response = TwitterTrend.Current(new CurrentTrendsOptions() { Proxy = OptionalProperties.Proxy, UseSSL = OptionalProperties.UseSSL });
            return response.ResponseObject;
        }

        public static TwitterDirectMessageCollection GetDirectMessages()
        {
            TwitterResponse<TwitterDirectMessageCollection> response = TwitterDirectMessage.DirectMessages(OAuthTokens, new DirectMessagesOptions() { Proxy = OptionalProperties.Proxy, UseSSL = OptionalProperties.UseSSL });
            return response.ResponseObject;
        }

        public static TwitterDirectMessage SendDirectMessage(string screenname, string text)
        {
            TwitterResponse<TwitterDirectMessage> response = TwitterDirectMessage.Send(OAuthTokens, screenname, text, OptionalProperties);
            return response.ResponseObject;
        }

        public static TwitterDirectMessageCollection GetSentDirectMessages()
        {
            TwitterResponse<TwitterDirectMessageCollection> response = TwitterDirectMessage.DirectMessagesSent(OAuthTokens, new DirectMessagesSentOptions() { Proxy = OptionalProperties.Proxy, UseSSL = OptionalProperties.UseSSL });
            return response.ResponseObject;
        }

        public static TwitterStatus PostUpdate(string text)
        {
            TwitterResponse<TwitterStatus> response = TwitterStatus.Update(OAuthTokens, text, new StatusUpdateOptions() { Proxy = Twillo.Core.Web.Proxy.WebProxy, UseSSL = SettingsManager.UseSSL });
            return response.ResponseObject;
        }

        public static TwitterStatus ReTweet(TwitterStatus message)
        {
            TwitterResponse<TwitterStatus> response = message.Retweet(OAuthTokens, OptionalProperties);
            return response.ResponseObject;
        }

        public static TwitterUser ReportUserAsSpam(string screenName)
        {
            TwitterResponse<TwitterUser> response = TwitterSpam.ReportUser(OAuthTokens, screenName, OptionalProperties);
            return response.ResponseObject;
        }

        public static TwitterUser ReportUserAsSpam(decimal userid)
        {
            TwitterResponse<TwitterUser> response = TwitterSpam.ReportUser(OAuthTokens, userid, OptionalProperties);
            return response.ResponseObject;
        }

        public static TwitterSearchResultCollection Search(string query)
        {
            TwitterResponse<TwitterSearchResultCollection> response = TwitterSearch.Search(OAuthTokens, query, new SearchOptions() { Proxy = OptionalProperties.Proxy, UseSSL = OptionalProperties.UseSSL });
            return response.ResponseObject;
        }

        public static TwitterUserCollection GetFollowers()
        {
            TwitterResponse<TwitterUserCollection> response = TwitterFriendship.Followers(OAuthTokens, new FollowersOptions() { Proxy = OptionalProperties.Proxy, UseSSL = OptionalProperties.UseSSL });
            return response.ResponseObject;
        }

        public static TwitterUserCollection GetFriends()
        {
            TwitterResponse<TwitterUserCollection> response = TwitterFriendship.Friends(OAuthTokens, new FriendsOptions() { Proxy = OptionalProperties.Proxy, UseSSL = OptionalProperties.UseSSL });
            return response.ResponseObject;
        }

        public static void GrantAccess()
        {
            string pin = "oob";
            OAuthTokenResponse response = OAuthUtility.GetRequestToken(SettingsManager.ConsumerKey, SettingsManager.ConsumerSecret, "oob", OptionalProperties.Proxy);
            Uri url = OAuthUtility.BuildAuthorizationUri(response.Token);
            Process.Start(url.ToString());

            Twillo.Core.Forms.frmAccessGrant frm = new Twillo.Core.Forms.frmAccessGrant();
            if (frm.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                pin = frm.AccessPin;
            }

            OAuthTokenResponse access = OAuthUtility.GetAccessToken(SettingsManager.ConsumerKey, SettingsManager.ConsumerSecret, response.Token, pin, OptionalProperties.Proxy);

            SettingsManager.Username = access.ScreenName;
            SettingsManager.AccessToken = access.Token;
            SettingsManager.AccessTokenSecret = access.TokenSecret;
            SettingsManager.UserId = access.UserId;
        }

    }
}
